package com.cold.demo.template.test;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.ScanIteration;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.TemporalField;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

public class GrabHPVForXF_MM {

    public static final Logger log = LoggerFactory.getLogger(GrabHPVForXF_MM.class.getSimpleName());

    private static volatile Map<String, List<String>> headers;

    static {
        generateHeader();
    }

    private static Map<String, List<String>> generateHeader() {
        if (headers != null) {
            return headers;
        }
        String hs = "Host: miaomiao.scmttec.com\n" +
                "Connection: keep-alive\n" +
                "Accept: application/json, text/plain, */*\n" +
                "Cookie: _xxhm_=%7B%22id%22%3A14114525%2C%22mobile%22%3A%2218615769932%22%2C%22nickName%22%3A%22%F0%9F%8C%B8%E3%80%80%E3%80%80%E9%A2%A8%E3%80%80%E3%80%80%F0%9F%92%8D%22%2C%22headerImg%22%3A%22http%3A%2F%2Fthirdwx.qlogo.cn%2Fmmopen%2FVicSudC46JREodsSQMBjyDuw9X8Xb4Mg3AyfuTkVLIMBo82HM98v129p7vKYllZtjfeeYlFX2iaGdiciaKO6XeOMGMZr9HqYKB2C%2F132%22%2C%22regionCode%22%3A%22510107%22%2C%22name%22%3A%22%E5%91%A8**%22%2C%22uFrom%22%3A%22depa_vacc_detail%22%2C%22wxSubscribed%22%3A1%2C%22birthday%22%3A%221995-09-26+00%3A00%3A00%22%2C%22sex%22%3A1%2C%22hasPassword%22%3Afalse%2C%22birthdayStr%22%3A%221995-09-26%22%7D; _xzkj_=wxapptoken:10:5f9e66e6079fc84cf4a2a175006fc2f3_f201fd107a4a3ac511449c1e589f3bb5; 8229=e46e9092dcc7aa3156; f1b5=7b1cb3420fc3b6ae42; 9c05=c001092aa986bad9e5; tgw_l7_route=b4da5575a1b8e2b7f3706bd11f4ee526; 7755=5259f5e08ce5ec05cd\n" +
                "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36 MicroMessenger/7.0.9.501 NetType/WIFI MiniProgramEnv/Windows WindowsWechat\n" +
                "X-Requested-With: XMLHttpRequest\n" +
                "content-type: application/json\n" +
                "ecc-hs: 7e067d8fdaad60c0d352af08a74856d6\n" +
                "tk: wxapptoken:10:5f9e66e6079fc84cf4a2a175006fc2f3_f201fd107a4a3ac511449c1e589f3bb5\n" +
                "Referer: https://servicewechat.com/wxff8cad2e9bf18719/21/page-frame.html\n" +
                "Accept-Encoding: gzip, deflate, br";

        String[] split = hs.split("\n");
        Map<String, List<String>> res = new HashMap<>();
        for (String s : split) {
            String sp = ": ";
            String key = s.split(sp)[0];
            String value = s.replace(key + sp, "");
            List<String> list = res.computeIfAbsent(key, k -> new ArrayList<>());
            list.add(value);
        }
        headers = res;
        return headers;
    }


    public static void main(String[] args) throws InterruptedException {
        generateHeader();
//        String responseBody = doGrabHPV("1106");
//        log.info("下单结果为：{}",responseBody);

        JSONArray data = queryHospital();
        log.info("查询到的所有医院数量：{}", data.size());
        for (Object datum : data) {
            JSONObject j = (JSONObject) datum;
            String seckillId = j.getString("id");
            String name = j.getString("name");
            String city = j.getString("city");
            String vaccineCode = j.getString("vaccineCode");
            String vaccineName = j.getString("vaccineName");
            String address = j.getString("address");
            String startTime = j.getString("startTime");// 抢疫苗的开始时间
            String stock = j.getString("stock");// 库存是否存在
            log.info("\n\t\t\tseckillId={}，city={}，startTime={}，name={}，stock={}，vaccineCode={}，vaccineName={}，address={}", seckillId, city, startTime, name, stock, vaccineCode, vaccineName, address);
        }
        sendOrder(data);

    }

    private static void sendOrder(JSONArray data) {
        for (Object datum : data) {
            JSONObject j = (JSONObject) datum;
            String seckillId = j.getString("id");
            String name = j.getString("name");
            String vaccineCode = j.getString("vaccineCode");
            String vaccineName = j.getString("vaccineName");
            String address = j.getString("address");
            String startTime = j.getString("startTime");// 抢疫苗的开始时间     2021-09-15 09:00:00
            String stock = j.getString("stock");// 库存是否存在             1 存在 0 不存在
            DateTime parse = DateUtil.parse(startTime, "yyyy-MM-dd HH:mm:ss");
            long time = parse.toJdkDate().getTime();
            if (System.currentTimeMillis() < time) {
                log.info("医院【{}】不在时间段内，该医院开始时间为 {}。", name, startTime);
                continue;
            }
            log.info("对医院【{}】下发订单信息。", name);
            String responseBody = doGrabHPV(seckillId);
            log.info("下单医院编号:{},结果为:{}", seckillId, responseBody);
        }
    }

    private static JSONArray queryHospital() {
        long startTime = System.currentTimeMillis();
        // 使用多线程查询
        ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        // 所有的城市地区以及相关的代号
        String s = "{\"5001\":\"重庆市\",\"6230\":\"甘南藏族自治州\",\"6110\":\"商洛市\",\"4290\":\"省直辖县级行政区划\",\"6590\":\"自治区直辖县级行政区划\",\"2306\":\"大庆市\",\"2305\":\"双鸭山市\",\"2304\":\"鹤岗市\",\"2303\":\"鸡西市\",\"2302\":\"齐齐哈尔市\",\"2301\":\"哈尔滨市\",\"6106\":\"延安市\",\"6105\":\"渭南市\",\"6229\":\"临夏回族自治州\",\"6108\":\"榆林市\",\"4601\":\"海口市\",\"6107\":\"汉中市\",\"4602\":\"三亚市\",\"4603\":\"三沙市\",\"6109\":\"安康市\",\"2309\":\"七台河市\",\"2308\":\"佳木斯市\",\"2307\":\"伊春市\",\"3406\":\"淮北市\",\"3405\":\"马鞍山市\",\"3404\":\"淮南市\",\"3403\":\"蚌埠市\",\"3402\":\"芜湖市\",\"3401\":\"合肥市\",\"2312\":\"绥化市\",\"2311\":\"黑河市\",\"2310\":\"牡丹江市\",\"3408\":\"安庆市\",\"3407\":\"铜陵市\",\"4190\":\"济源市\",\"4507\":\"钦州市\",\"3417\":\"池州市\",\"2207\":\"松原市\",\"4508\":\"贵港市\",\"3416\":\"亳州市\",\"2327\":\"大兴安岭地区\",\"2206\":\"白山市\",\"4509\":\"玉林市\",\"3415\":\"六安市\",\"2205\":\"通化市\",\"2204\":\"辽源市\",\"3413\":\"宿州市\",\"2203\":\"四平市\",\"3412\":\"阜阳市\",\"2202\":\"吉林市\",\"3411\":\"滁州市\",\"2201\":\"长春市\",\"3410\":\"黄山市\",\"4501\":\"南宁市\",\"4502\":\"柳州市\",\"4503\":\"桂林市\",\"4504\":\"梧州市\",\"4505\":\"北海市\",\"4506\":\"防城港市\",\"3418\":\"宣城市\",\"2208\":\"白城市\",\"3310\":\"台州市\",\"3307\":\"金华市\",\"3306\":\"绍兴市\",\"3305\":\"湖州市\",\"3304\":\"嘉兴市\",\"3303\":\"温州市\",\"3302\":\"宁波市\",\"3301\":\"杭州市\",\"4510\":\"百色市\",\"4511\":\"贺州市\",\"4512\":\"河池市\",\"4513\":\"来宾市\",\"4514\":\"崇左市\",\"3309\":\"舟山市\",\"3308\":\"衢州市\",\"2111\":\"盘锦市\",\"2110\":\"辽阳市\",\"4408\":\"湛江市\",\"2108\":\"营口市\",\"4409\":\"茂名市\",\"2107\":\"锦州市\",\"2106\":\"丹东市\",\"2105\":\"本溪市\",\"2104\":\"抚顺市\",\"2224\":\"延边朝鲜族自治州\",\"2103\":\"鞍山市\",\"2102\":\"大连市\",\"3311\":\"丽水市\",\"2101\":\"沈阳市\",\"4401\":\"广州市\",\"4402\":\"韶关市\",\"4403\":\"深圳市\",\"4404\":\"珠海市\",\"4405\":\"汕头市\",\"4406\":\"佛山市\",\"4407\":\"江门市\",\"2109\":\"阜新市\",\"8101\":\"香港\",\"4420\":\"中山市\",\"3211\":\"镇江市\",\"3210\":\"扬州市\",\"1390\":\"省直辖县级行政区划\",\"4419\":\"东莞市\",\"3208\":\"淮安市\",\"3207\":\"连云港市\",\"3206\":\"南通市\",\"3205\":\"苏州市\",\"3204\":\"常州市\",\"3203\":\"徐州市\",\"2114\":\"葫芦岛市\",\"3202\":\"无锡市\",\"2113\":\"朝阳市\",\"3201\":\"南京市\",\"2112\":\"铁岭市\",\"4412\":\"肇庆市\",\"4413\":\"惠州市\",\"4414\":\"梅州市\",\"4415\":\"汕尾市\",\"4416\":\"河源市\",\"4417\":\"阳江市\",\"4418\":\"清远市\",\"3209\":\"盐城市\",\"4310\":\"郴州市\",\"4311\":\"永州市\",\"4309\":\"益阳市\",\"3213\":\"宿迁市\",\"3212\":\"泰州市\",\"4301\":\"长沙市\",\"4302\":\"株洲市\",\"4303\":\"湘潭市\",\"4304\":\"衡阳市\",\"4305\":\"邵阳市\",\"4306\":\"岳阳市\",\"4307\":\"常德市\",\"4308\":\"张家界市\",\"4201\":\"武汉市\",\"4312\":\"怀化市\",\"5401\":\"拉萨市\",\"4313\":\"娄底市\",\"5402\":\"日喀则市\",\"5403\":\"昌都市\",\"5404\":\"林芝市\",\"4690\":\"省直辖县级行政区划\",\"4451\":\"潮州市\",\"4210\":\"荆州市\",\"4331\":\"湘西土家族苗族自治州\",\"4452\":\"揭阳市\",\"4211\":\"黄冈市\",\"4453\":\"云浮市\",\"4212\":\"咸宁市\",\"5422\":\"山南地区\",\"5301\":\"昆明市\",\"4202\":\"黄石市\",\"6502\":\"克拉玛依市\",\"4203\":\"十堰市\",\"6501\":\"乌鲁木齐市\",\"6504\":\"吐鲁番市\",\"4205\":\"宜昌市\",\"4206\":\"襄阳市\",\"4207\":\"鄂州市\",\"4208\":\"荆门市\",\"4209\":\"孝感市\",\"4101\":\"郑州市\",\"6522\":\"哈密地区\",\"6401\":\"银川市\",\"4102\":\"开封市\",\"1503\":\"乌海市\",\"1502\":\"包头市\",\"1501\":\"呼和浩特市\",\"4213\":\"随州市\",\"5424\":\"那曲地区\",\"5303\":\"曲靖市\",\"5425\":\"阿里地区\",\"5304\":\"玉溪市\",\"1509\":\"乌兰察布市\",\"5305\":\"保山市\",\"1508\":\"巴彦淖尔市\",\"5306\":\"昭通市\",\"1507\":\"呼伦贝尔市\",\"5307\":\"丽江市\",\"1506\":\"鄂尔多斯市\",\"5308\":\"普洱市\",\"1505\":\"通辽市\",\"5309\":\"临沧市\",\"1504\":\"赤峰市\",\"4110\":\"许昌市\",\"6531\":\"喀什地区\",\"4111\":\"漯河市\",\"6530\":\"克孜勒苏柯尔克孜自治州\",\"4112\":\"三门峡市\",\"5201\":\"贵阳市\",\"4113\":\"南阳市\",\"5202\":\"六盘水市\",\"6532\":\"和田地区\",\"5323\":\"楚雄彝族自治州\",\"4103\":\"洛阳市\",\"6403\":\"吴忠市\",\"4104\":\"平顶山市\",\"6523\":\"昌吉回族自治州\",\"6402\":\"石嘴山市\",\"4105\":\"安阳市\",\"6405\":\"中卫市\",\"4106\":\"鹤壁市\",\"6404\":\"固原市\",\"4107\":\"新乡市\",\"4228\":\"恩施土家族苗族自治州\",\"6528\":\"巴音郭楞蒙古自治州\",\"4108\":\"焦作市\",\"6527\":\"博尔塔拉蒙古自治州\",\"4109\":\"濮阳市\",\"6529\":\"阿克苏地区\",\"6540\":\"伊犁哈萨克自治州\",\"6542\":\"塔城地区\",\"5331\":\"德宏傣族景颇族自治州\",\"6302\":\"海东市\",\"5333\":\"怒江傈僳族自治州\",\"6543\":\"阿勒泰地区\",\"6301\":\"西宁市\",\"5334\":\"迪庆藏族自治州\",\"1404\":\"长治市\",\"3704\":\"枣庄市\",\"1525\":\"锡林郭勒盟\",\"1403\":\"阳泉市\",\"3705\":\"东营市\",\"1402\":\"大同市\",\"3706\":\"烟台市\",\"1401\":\"太原市\",\"3707\":\"潍坊市\",\"1522\":\"兴安盟\",\"3708\":\"济宁市\",\"3709\":\"泰安市\",\"4114\":\"商丘市\",\"5203\":\"遵义市\",\"4115\":\"信阳市\",\"5204\":\"安顺市\",\"5325\":\"红河哈尼族彝族自治州\",\"4116\":\"周口市\",\"5205\":\"毕节市\",\"5326\":\"文山壮族苗族自治州\",\"1409\":\"忻州市\",\"4117\":\"驻马店市\",\"5206\":\"铜仁市\",\"1408\":\"运城市\",\"5328\":\"西双版纳傣族自治州\",\"1529\":\"阿拉善盟\",\"1407\":\"晋中市\",\"3701\":\"济南市\",\"5329\":\"大理白族自治州\",\"1406\":\"朔州市\",\"3702\":\"青岛市\",\"1405\":\"晋城市\",\"3703\":\"淄博市\",\"5101\":\"成都市\",\"5223\":\"黔西南布依族苗族自治州\",\"5103\":\"自贡市\",\"3715\":\"聊城市\",\"3716\":\"滨州市\",\"3717\":\"菏泽市\",\"1411\":\"吕梁市\",\"1410\":\"临汾市\",\"3710\":\"威海市\",\"3711\":\"日照市\",\"3713\":\"临沂市\",\"3714\":\"德州市\",\"5110\":\"内江市\",\"5111\":\"乐山市\",\"6322\":\"海北藏族自治州\",\"6201\":\"兰州市\",\"5113\":\"南充市\",\"6203\":\"金昌市\",\"5114\":\"眉山市\",\"6323\":\"黄南藏族自治州\",\"6202\":\"嘉峪关市\",\"3604\":\"九江市\",\"1305\":\"邢台市\",\"3603\":\"萍乡市\",\"1304\":\"邯郸市\",\"3602\":\"景德镇市\",\"1303\":\"秦皇岛市\",\"3601\":\"南昌市\",\"1302\":\"唐山市\",\"1301\":\"石家庄市\",\"5104\":\"攀枝花市\",\"5105\":\"泸州市\",\"5226\":\"黔东南苗族侗族自治州\",\"5106\":\"德阳市\",\"5227\":\"黔南布依族苗族自治州\",\"3609\":\"宜春市\",\"5107\":\"绵阳市\",\"3608\":\"吉安市\",\"1309\":\"沧州市\",\"5108\":\"广元市\",\"3607\":\"赣州市\",\"1308\":\"承德市\",\"5109\":\"遂宁市\",\"3606\":\"鹰潭市\",\"1307\":\"张家口市\",\"3605\":\"新余市\",\"1306\":\"保定市\",\"5120\":\"资阳市\",\"6210\":\"庆阳市\",\"6212\":\"陇南市\",\"6211\":\"定西市\",\"3611\":\"上饶市\",\"3610\":\"抚州市\",\"1311\":\"衡水市\",\"1310\":\"廊坊市\",\"5115\":\"宜宾市\",\"6326\":\"果洛藏族自治州\",\"6205\":\"天水市\",\"5116\":\"广安市\",\"6325\":\"海南藏族自治州\",\"6204\":\"白银市\",\"5117\":\"达州市\",\"6328\":\"海西蒙古族藏族自治州\",\"6207\":\"张掖市\",\"5118\":\"雅安市\",\"6327\":\"玉树藏族自治州\",\"6206\":\"武威市\",\"5119\":\"巴中市\",\"6209\":\"酒泉市\",\"6208\":\"平凉市\",\"5132\":\"阿坝藏族羌族自治州\",\"5133\":\"甘孜藏族自治州\",\"6102\":\"铜川市\",\"5134\":\"凉山彝族自治州\",\"6101\":\"西安市\",\"6104\":\"咸阳市\",\"6103\":\"宝鸡市\",\"3505\":\"泉州市\",\"3504\":\"三明市\",\"3503\":\"莆田市\",\"3502\":\"厦门市\",\"3501\":\"福州市\",\"3509\":\"宁德市\",\"3508\":\"龙岩市\",\"3507\":\"南平市\",\"3506\":\"漳州市\"}";
        JSONObject m = JSON.parseObject(s);

        final JSONArray data = new JSONArray();
        for (Map.Entry<String, Object> entry : m.getInnerMap().entrySet()) {
            Future<String> submit = threadPool.submit(() -> {
                String k = entry.getKey();
                String v = entry.getValue().toString();
                if (!Arrays.asList("重庆市", "成都市").contains(v)) {
                    return "";
                }
                String url = "https://miaomiao.scmttec.com/seckill/seckill/list.do?offset=0&limit=10&regionCode=" + k;
                HttpRequest request = HttpUtil.createGet(url);
                request.header(headers);
                HttpResponse execute = request.execute();
                String body = execute.body();
                JSONObject jsonObject;
                try {
                    jsonObject = JSONObject.parseObject(body);
                } catch (Exception e) {
                    log.error("本次查询地区({}-{})是否存在疫苗，查询失败，结果为：{}", k, v, body);
                    return "";
                }
                log.info("本次查询地区({}-{})是否存在疫苗，查询成功，结果为：{}", k, v, body);
                if ("0000".equals(jsonObject.getString("code"))) {
                    data.addAll(jsonObject.getJSONArray("data").stream()
                            .peek(r -> ((JSONObject) r).put("city", v))
                            .collect(Collectors.toList()));
                } else if ("1001".equals(jsonObject.getString("code"))) {
                    log.error(String.format("登录超时%s:%s", LocalDateTime.now(), body));
                } else {
                    log.error("请求服务器异常,异常信息：{}", body);
                }
                return "";
            });
        }
        threadPool.shutdown();
        try {
            threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        log.info("查询所有医院耗时：{}ms", (endTime - startTime));
        return data;
    }

    private static String doGrabHPV(String seckillId) {
        try {
            Map<String, Object> params = new HashMap<>();
            params.put("seckillId", seckillId);// 存在疫苗的医院id
            params.put("linkmanId", "17228807");// 小凤的id值写死不动
            params.put("idCardNo", "513021199602274320");//小凤的身份证号写死不动
            params.put("vaccineIndex", 1);// 疫苗索引  暂时写死
            String url = "https://miaomiao.scmttec.com/seckill/seckill/subscribe.do";// 提交订单
            HttpRequest submitOrderRequest = HttpUtil.createGet(url);
            submitOrderRequest.header(generateHeader());
            submitOrderRequest.form(params);
            HttpResponse submitOrderResponse = submitOrderRequest.execute();
            return submitOrderResponse.body();
        } catch (Exception e) {
            log.error("下单发送异常", e);
            e.printStackTrace();
            return "请求异常";
        }
    }

    @Test
    public void test2()throws Exception{
        System.out.println(doGrabHPV("1166"));
    }

    @Test
    public void test1() throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
        long beginTime = DateUtil.date(LocalDateTime.of(2021, 10, 18, 14, 59, 50)).toJdkDate().getTime(); // 在这个时间的时候开始抢购
        long stopTime = DateUtil.date(LocalDateTime.of(2021, 10, 18, 15, 0, 30)).toJdkDate().getTime(); // 截止这个时间就不抢了

        ReentrantLock streamLock = new ReentrantLock();
        FileOutputStream fos = new FileOutputStream("E:\\temp\\hpv.log");
        try {
            while (System.currentTimeMillis() < stopTime) {
                if (System.currentTimeMillis() < beginTime) {
                    System.out.println("还未到开始抢单时间，500毫秒后持续监测...当前时间为：" + LocalDateTime.now());
                    Thread.sleep(500);
                    continue;
                }
                List<String> ids = Arrays.asList("1162", "1163", "1164");
                for (String seckillId : ids) {
                    executorService.execute(() -> {
                        String s1 = doGrabHPV(seckillId);
                        writeLine(fos,streamLock,s1);
                    });
                }
                Thread.sleep(1);
            }
        } finally {
            executorService.shutdown();
            while (true) {
                if (executorService.isTerminated()) {
                    streamLock.lock();
                    IoUtil.close(fos);
                    streamLock.unlock();
                    System.out.println("已关闭线程池...");
                    break;
                }
                Thread.sleep(1000);
                System.out.println("正在关闭线程池中...");
            }
        }
    }

    private void writeLine(FileOutputStream fos, ReentrantLock streamLock, String s1) {
        try {
            streamLock.lock();
            fos.write(s1.getBytes(StandardCharsets.UTF_8));
            fos.write("\n".getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IoUtil.flush(fos);
            streamLock.unlock();
        }
    }
}
